import { Message } from "element-ui";
import { isString } from "is-type-data";
import eventCallbacks from "../eventCallbacks";

const generateInputCallback = (form, field) => {
  return (value) => {
    form[field] = value;
  };
};

const getCustomEventCallback = (event) => {
  let executor = () => {};
  const { name } = event.executor;
  if (Array.isArray(name)) {
    name.forEach((item, i) => {
      if (i === 0) {
        executor = eventCallbacks[item];
      } else {
        executor = executor[item];
      }
    });
  } else {
    executor = eventCallbacks["service"];
  }

  return executor;
};

export const loopModel = (VNode) => {
  const { tag, config, children } = VNode;
  if (tag === "el-form") {
    return config.props.model;
  }
  if (Array.isArray(children) && children.length > 0) {
    for (let index = 0; index < children.length; index++) {
      const element = children[index];
      return loopModel(element);
    }
  }
};

export const loopNodeTemplateName = (VNode, targetTag = "el-form") => {
  const { tag, config, children } = VNode;
  if (tag === targetTag) {
    return config.props.templateName;
  }
  if (Array.isArray(children) && children.length > 0) {
    for (let index = 0; index < children.length; index++) {
      const element = children[index];
      return loopNodeTemplateName(element);
    }
  }
};

const isDisabled = (disabled, form) => {
  const { relation, logic = "or" } = disabled || {};
  if (relation && Array.isArray(relation) && relation.length > 0) {
    if (logic === "and") {
      return !relation.every((item) => form[item.field]);
    }
    if (logic === "or") {
      return !relation.some((item) => form[item.field]);
    }
  }

  return false;
};

export const create = function (data, h, form) {
  const { tag, config, children, events, disabled, hiddenOn } = data;
  if (hiddenOn) {
    if (!form["name"]) return null;
  }
  if (tag === "el-input" || tag === "el-date-picker") {
    const { __field } = config.props;
    config.props.value = form[__field];
    config.props.disabled = isDisabled(disabled, form);
    if (config.on && !config.on.input) {
      config.on.input = generateInputCallback(form, __field);
    }

    if (!config.on) {
      config.on = {};
    }
    config.on.input = generateInputCallback(form, __field);
  }
  if (tag === "el-button") {
    if (Array.isArray(events)) {
      events.forEach((event) => {
        if (!config.on) {
          config.on = {};
        }
        const { eventName } = event;
        config.on[eventName] = async () => {
          const { executorConfig } = event.executor;
          if (executorConfig && executorConfig.isVerify) {
            // 校验表单必填项
            const result = await this.$refs["el-form-1"]
              .validate()
              .then((data) => true)
              .catch((error) => false);
            if (!result) {
              Message.warning(executorConfig.message || "请完善表单必填项");
              return;
            }
          }
          const fn = getCustomEventCallback(event);
          return fn(event.executor.params, form);
        };
      });
    }
  }

  if (tag === "aegle-select") {
    const { __field } = config.props;
    config.props.value = form[__field];
    config.props.disabled = isDisabled(disabled, form);
    if (config.on && !config.on.input) {
      config.on.input = generateInputCallback(form, __field);
    }

    if (!config.on) {
      config.on = {};
    }
    config.on.input = generateInputCallback(form, __field);
  }

  if (children && Array.isArray(children) && children.length) {
    const creates = children.map((child) => {
      if (isString(child)) {
        return child;
      }
      return create.call(this, child, h, form);
    });
    return h(tag, config, creates);
  } else {
    return h(tag, config);
  }
};
